
#include <mpi.h>
#include "message.h"
#include "params.h"
#include "stopcond.h"
#include "nnengine.h"

using namespace std;

int main (int argc, char** argv) {
	Message		*message     = NULL;
	Parameters 	*params      = NULL;
	NeuralNetworkEngine* nn  = NULL;
	int do_compress=0;
	int rc, rank, root=0;

	struct timespec start;
	struct timespec stop;
	double elapsed;
	clock_gettime(CLOCK_REALTIME, &start);
	
	rc = MPI_Init(&argc,&argv);
	if (rc != MPI_SUCCESS) 
	{
		printf ("Error starting MPI program. Terminating.\n");
		MPI_Abort(MPI_COMM_WORLD, rc);
	}
	
	MPI_Comm_rank(MPI_COMM_WORLD,&rank);
	
	if (rank == root) {

		message = new Message();
		params  = new Parameters(message);
	
		message->showWelcome();
		
		params->analyseComandLine(argc, argv);
		
		if (params->hasErrors())
			message->showUsageMPI();

		if (params->mustCompress()) 
			do_compress=1;

		if (params->mustDecompress()) {
			nn = new NeuralNetworkEngine(params, message);	
			nn->transformNDFintoBMP();
		}			
	}

	MPI_Bcast(&do_compress, 1, MPI_INT, root, MPI_COMM_WORLD);
	
	if (do_compress==1)
	{
		nn = new NeuralNetworkEngine(params, message);	
		nn->transformBMPintoNGF();
	}
		
	if (rank==root) {
		if ((nn!=NULL) && (nn->hasErrors()))
			message->printMessage("Errors were encountered. Exiting.\n");
		
		// clock finish:
		clock_gettime(CLOCK_REALTIME, &stop);
		elapsed=(double)(stop.tv_sec-start.tv_sec)+(double)(stop.tv_nsec-start.tv_nsec)/1e9;
		message->printMessage("Time elapsed: ");
		message->printMessage(elapsed);
		message->printMessage(".\n");

	}
	
	if (nn!=NULL)      delete nn;
	if (params!=NULL)  delete params;
	if (message!=NULL) delete message;

	MPI_Finalize();
	
	return 0;
	
}
